import AsyncStorage from '@react-native-community/async-storage';
import { filter, equals, forEach, clone } from 'ramda';

import { DownloadVideoTaskProps, SortedDownloadVideoTasks } from './types';

// 视频缓存队列
const STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE = 'downloadVideoTaskQueue';

// 仅WIFI下载
const STORAGE_KEY_ONLY_WIFI_DOWNLOAD = 'onlyWifiDownload';

let videoTaskQueue: DownloadVideoTaskProps[] = [];

let userLessonResourceIds: number[] = [];

export const emptyVideoTaskItem: DownloadVideoTaskProps = {
  id: 0, // id
  title: '', // title
  type: 0, // 视频type -ld -sd -hd
  urls: [], // m3u8的url
  size: 0, // 预计总文件大小
  progress: 0, // 总下载进度
  indexHaveDone: [], // m3u8索引是否下载完成
  keyHaveDone: [], // 密钥是否下载完成
  m3u8Paths: [], // 本地m3u8路径
  parentId: 0, // 父级id
  parentTitle: '', // 父级title
  isPaused: false, // 是否暂停
  isFailed: false, // 是否失败
  startTime: '', // 下载开始时间
  source: '', // 视频来源
  tsDoneNum: 0
};

export const emptySortedDownloadVideoTasks: SortedDownloadVideoTasks = {
  parentId: 0,
  parentTitle: '',
  totalSize: 0,
  progress: 0,
  source: '',
  videoTasks: [],
  isPaused: false, // 是否暂停
  isFailed: false // 是否失败
};

AsyncStorage.getItem(STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE).then(
  (res: any): void => {
    if (res) {
      videoTaskQueue = JSON.parse(res) || [];
    }
  }
);

// 设置当前用户拥有的lessonResourceIds
export const setUserLessonResourceIds = (data: number[]): void => {
  userLessonResourceIds = data;
};

// 过滤该用户所有课程的视频下载任务
const filterUserDownloadTaskQueue = (): DownloadVideoTaskProps[] => {
  if (userLessonResourceIds.length === 0) return videoTaskQueue;

  const filterVideoTaskQueue = videoTaskQueue.filter((item): boolean =>
    userLessonResourceIds.includes(item.parentId)
  );
  return filterVideoTaskQueue;
};

// 设置某项视频缓存信息
export const setStoreVideoTask = (
  data: Partial<DownloadVideoTaskProps>
): void => {
  const { id = 0, ...otherData } = data;
  if (id) {
    const index = videoTaskQueue.findIndex((item): boolean => item.id === id);
    if (index !== -1) {
      videoTaskQueue[index] = { ...videoTaskQueue[index], ...otherData, id };
    } else {
      videoTaskQueue.push({ ...emptyVideoTaskItem, ...otherData, id });
    }
    AsyncStorage.setItem(
      STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE,
      JSON.stringify(videoTaskQueue)
    );
  }
};

// 从头插入视频下载任务到视频缓存队列
export const unshiftStoreVideoTaskQueue = (
  data: Partial<DownloadVideoTaskProps>
): void => {
  const { id = 0, ...otherData } = data;
  if (id) {
    const index = videoTaskQueue.findIndex((item): boolean => item.id === id);
    if (index !== -1) {
      videoTaskQueue.splice(index, 1);
    }
    videoTaskQueue.unshift({ ...emptyVideoTaskItem, ...otherData, id });
    AsyncStorage.setItem(
      STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE,
      JSON.stringify(videoTaskQueue)
    );
  }
};

// 获取全部视频下载任务
export const getAllStoreVideoTasks = (): DownloadVideoTaskProps[] => {
  return filterUserDownloadTaskQueue();
};

// 获取未完成的视频下载任务
export const getUnFinishedStoreVideoTasks = (): DownloadVideoTaskProps[] => {
  return filterUserDownloadTaskQueue().filter((task): boolean => {
    const { indexHaveDone, keyHaveDone, progress } = task;
    const allIndexHaveDone = indexHaveDone.every((item): boolean => item);
    const allKeyHaveDone = keyHaveDone.every((item): boolean => item);
    return !allIndexHaveDone || !allKeyHaveDone || progress < 1;
  });
};

// 获取下载完成的视频下载任务
export const getFinishedStoreVideoTasks = (): DownloadVideoTaskProps[] => {
  const finishedVideos: DownloadVideoTaskProps[] = [];
  filterUserDownloadTaskQueue().forEach((task): void => {
    const { indexHaveDone, keyHaveDone, progress } = task;
    const allIndexHaveDone = indexHaveDone.every((item): boolean => item);
    const allKeyHaveDone = keyHaveDone.every((item): boolean => item);
    if (allIndexHaveDone && allKeyHaveDone && progress >= 1) {
      finishedVideos.unshift(task);
    }
  });
  return finishedVideos;
};

// 获取一个视频下载任务
export const getStoreVideoTask = (
  id: number | string
): DownloadVideoTaskProps | undefined => {
  const videoTask = filterUserDownloadTaskQueue().find(
    (item): boolean => item.id === id
  );
  return videoTask;
};

// 获取最近的视频下载任务
export const getLatestStoreVideoTask = ():
  | DownloadVideoTaskProps
  | undefined => {
  const videoTask = filterUserDownloadTaskQueue().find((task): boolean => {
    const { indexHaveDone, keyHaveDone, progress, isPaused, isFailed } = task;
    const allIndexHaveDone = indexHaveDone.every((item): boolean => item);
    const allKeyHaveDone = keyHaveDone.every((item): boolean => item);
    return (
      (!allIndexHaveDone || !allKeyHaveDone || progress < 1) &&
      !isPaused &&
      !isFailed
    );
  });
  return videoTask;
};

// 删除某个视频下载任务
export const deleteStoreVideoTask = (id: number | string): void => {
  const index = videoTaskQueue.findIndex((item): boolean => item.id === id);
  if (index !== -1) {
    videoTaskQueue.splice(index, 1);
    AsyncStorage.setItem(
      STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE,
      JSON.stringify(videoTaskQueue)
    );
  }
};

// 删除全部视频下载任务
export const deleteAllStoreVideoTasks = (): void => {
  videoTaskQueue = [];
  AsyncStorage.removeItem(STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE);
};

// 获取某个parentId的视频下载任务
export const getSortedStoreVideoTask = (
  expectParentId: number
): SortedDownloadVideoTasks => {
  const allVideoTasks = getAllStoreVideoTasks();
  let sortedVideoTask = {
    ...emptySortedDownloadVideoTasks,
    parentId: expectParentId
  };

  allVideoTasks.forEach((task): void => {
    const { parentId, parentTitle, source } = task;

    if (parentId !== expectParentId) {
      return;
    }
    if (sortedVideoTask.videoTasks.length === 0) {
      sortedVideoTask = {
        ...sortedVideoTask,
        parentTitle,
        source,
        progress: 0,
        totalSize: task.size,
        videoTasks: [task]
      };
    } else {
      sortedVideoTask.videoTasks.unshift(task);
      sortedVideoTask = {
        ...sortedVideoTask,
        totalSize: sortedVideoTask.totalSize + task.size
      };
    }
  });

  let downloadedSize = 0;
  const { videoTasks, totalSize } = sortedVideoTask;
  videoTasks.forEach((task): void => {
    downloadedSize += task.progress * task.size;
  });

  sortedVideoTask.progress = downloadedSize / totalSize;
  sortedVideoTask.isPaused = videoTasks.every((item): boolean => item.isPaused);
  sortedVideoTask.isFailed = videoTasks.some((item): boolean => item.isFailed);

  return sortedVideoTask;
};

// 获取归类的视频下载任务列表
export const getSortedStoreVideoTaskList = (): SortedDownloadVideoTasks[] => {
  const allVideoTasks = getAllStoreVideoTasks();
  const sortedVideoTaskList: SortedDownloadVideoTasks[] = [];

  allVideoTasks.forEach((task): void => {
    const { parentId, parentTitle, source } = task;
    const index = sortedVideoTaskList.findIndex(
      (videos): boolean => videos.parentId === parentId
    );
    if (index === -1 || parentId === 0) {
      sortedVideoTaskList.push({
        parentId,
        parentTitle,
        progress: 0,
        source,
        totalSize: task.size,
        videoTasks: [task],
        isPaused: false,
        isFailed: false
      });
    } else {
      sortedVideoTaskList[index].videoTasks.unshift(task);
      sortedVideoTaskList[index] = {
        ...sortedVideoTaskList[index],
        totalSize: sortedVideoTaskList[index].totalSize + task.size
      };
    }
  });

  sortedVideoTaskList.forEach(({ videoTasks, totalSize }, index): void => {
    let downloadedSize = 0;
    videoTasks.forEach((task): void => {
      downloadedSize += task.progress * task.size;
    });
    sortedVideoTaskList[index].progress = downloadedSize / totalSize;
    sortedVideoTaskList[index].isPaused = videoTasks.every(
      (item): boolean => item.isPaused
    );
    sortedVideoTaskList[index].isFailed = videoTasks.some(
      (item): boolean => item.isFailed
    );
  });

  return sortedVideoTaskList;
};

// 根据parentId获取视频下载任务
export const getVideoTasksByParentId = (
  parentId: number
): { [key: string]: DownloadVideoTaskProps } => {
  const filterByParentId = (item: DownloadVideoTaskProps): boolean =>
    equals(item.parentId)(parentId);

  const videos = filter(filterByParentId)(filterUserDownloadTaskQueue());

  const videoTasksObject: { [key: string]: DownloadVideoTaskProps } = {};

  forEach((item: DownloadVideoTaskProps): void => {
    videoTasksObject[String(item.id)] = item;
  })(videos);

  return videoTasksObject;
};

// 获取正在进行的下载任务
export const getDownloadingVideoTasks = (): void => {};

export const getDownloadingStoreVideoTasks = (): DownloadVideoTaskProps[] => {
  return filterUserDownloadTaskQueue().filter((task): boolean => {
    const { indexHaveDone, keyHaveDone, progress, isPaused } = task;
    const allIndexHaveDone = indexHaveDone.every((item): boolean => item);
    const allKeyHaveDone = keyHaveDone.every((item): boolean => item);
    return (!allIndexHaveDone || !allKeyHaveDone || progress < 1) && !isPaused;
  });
};

// // 判断缓存中某个下载任务是否下载完成
// export const getStoreVideoTaskIsFinished = (id: number | string): boolean => {
//   let isFinished = false;
//   const task = getStoreVideoTask(id);
//   if (task) {
//     const { indexHaveDone, keyHaveDone, progress } = task;
//     const allIndexHaveDone = indexHaveDone.every((item): boolean => item);
//     const allKeyHaveDone = keyHaveDone.every((item): boolean => item);
//     isFinished = allIndexHaveDone && allKeyHaveDone && progress >= 1;
//   }
//   return isFinished;
// };

// // 压缩下载队列
// export const compressDownloadQueue = (): void => {
//   const parentIdRelation: {
//     [key: number]: { pos: number; isFinished: boolean }[];
//   } = {};

//   videoTaskQueue.forEach(({ id, parentId }, index): void => {
//     if (parentIdRelation[parentId]) {
//       parentIdRelation[parentId] = [
//         ...parentIdRelation[parentId],
//         { pos: index, isFinished: getStoreVideoTaskIsFinished(id) }
//       ];
//     } else {
//       parentIdRelation[parentId] = [
//         { pos: index, isFinished: getStoreVideoTaskIsFinished(id) }
//       ];
//     }
//   });

//   Object.values(parentIdRelation).forEach((relation): void => {
//     const canCompressed = relation.every(item => item.isFinished);
//     if (canCompressed) {
//       relation.forEach((item, index): void => {
//         videoTaskQueue[index].tsList = [];
//       });
//     }
//   });

//   AsyncStorage.setItem(
//     STORAGE_KEY_DOWNLOAD_VIDEO_TASK_QUEUE,
//     JSON.stringify(videoTaskQueue)
//   );
// };

let onlyWifiDownload: { [key: string]: boolean } = {}; // 仅wifi下载
AsyncStorage.getItem(STORAGE_KEY_ONLY_WIFI_DOWNLOAD).then((res: any): void => {
  if (res) {
    onlyWifiDownload = JSON.parse(res);
  }
});

export const setOnlyWifiDownload = (userId: string, value: boolean): void => {
  onlyWifiDownload[userId] = value;
  AsyncStorage.setItem(
    STORAGE_KEY_ONLY_WIFI_DOWNLOAD,
    JSON.stringify(onlyWifiDownload)
  );
};

export const getOnlyWifiDownload = (userId: string): boolean => {
  // return onlyWifiDownload[userId] === undefined
  //   ? true
  //   : onlyWifiDownload[userId];
  return false;
};
